package secondriver.process.handler;

import java.text.NumberFormat;
import java.text.ParseException;
import java.util.function.Supplier;
import net.coobird.thumbnailator.geometry.Positions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import secondriver.process.exception.ArgumentInvalidException;
import spark.utils.StringUtils;

/**
 * Author : secondriver
 * Date :  2016/1/5
 */
public enum Param {

    /**
     * 尺寸设置模式
     * <p>
     * mode=scale|size
     */
    MODE("mode"),

    /**
     * 尺寸值设置 modeValue
     * <p>
     * if mode=scale modeValue=widthScale_heightScale
     * <p>
     * if mode=size modeValue = width_height
     */
    MODE_VALUE("modeValue"),

    /**
     * 图片输出方式
     * <p>
     * Stream:流输出
     * URL: 图片Url地址重定向
     * Base64:图片内容通过utf-8,Base64编码之后输出：
     */
    OUTPUT_TYPE("outputType"),

    /**
     * 是否保持宽高方向的缩放比例
     * <p>
     * if mode=size keepAspectRatio=false 不保持
     * <p>
     * if mode=size keepAspectRatio=true 保持
     * <p>
     * if mode= scale 忽略
     */
    KEEP_ASPECT_RATIO("keepAspectRatio"),

    /**
     * 原始图片
     * <p>
     * source=url/filename(相对于外部静态文件路径的文件名)
     */
    SOURCE("source"),

    /**
     * 图片质量
     * <p>
     * quality="[0.0,1.0]"
     */
    QUALITY("quality"),

    /**
     * 裁剪位置
     * <p>
     * if mode =size 可用,cropPosition 取值如下(忽略大小写)
     * BOTTOM_CENTER
     * BOTTOM_LEFT
     * BOTTOM_RIGHT
     * CENTER
     * CENTER_LEFT
     * CENTER_RIGHT
     * TOP_CENTER
     * TOP_LEFT
     * TOP_RIGHT
     * <p>
     * if mode=scale 不可用
     */
    CROP_POSITION("cropPosition"),

    /**
     * 旋转角度
     * <p>
     * if rotateAngle < 0 left rotate
     * <p>
     * if rotateAngle > 0 right rotate
     */
    ROTATE_ANGLE("rotateAngle"),

    /**
     * 水印图片
     * <p>
     * watermark=url/(相对于外部静态文件路径的文件名)
     */
    WATERMARK("watermark"),

    /**
     * 水印图片尺寸设置模式
     * <p>
     * mode=scale|size
     */
    WATERMARK_MODE("watermarkMode"),

    /**
     * 水印图片尺寸值设置 modeValue
     * <p>
     * if mode=scale modeValue=widthScale_heightScale
     * <p>
     * if mode=size modeValue = width_height
     */
    WATERMARK_MODE_VALUE("watermarkModeValue"),

    /**
     * 水印图片位置
     * <p>
     * watermarkPosition取值如下(忽略大小写)
     * BOTTOM_CENTER
     * BOTTOM_LEFT
     * BOTTOM_RIGHT
     * CENTER
     * CENTER_LEFT
     * CENTER_RIGHT
     * TOP_CENTER
     * TOP_LEFT
     * TOP_RIGHT
     */
    WATERMARK_POSITION("watermarkPosition"),

    /**
     * 水印图片透明度
     * <p>
     * watermarkOpacity=[0.0,1.0]
     */
    WATERMARK_OPACITY("watermarkOpacity");

    private static final Logger LOGGER = LoggerFactory.getLogger(Param.class);

    /**
     * 默认modeValue=1.0_1.0
     * <p>
     * 如果mode=scale, 默认modeValue=1.0_1.0
     * 如果mode=scale, 默认modeValue=1.0*MAX_1.0*MAX
     */
    public static ModeValue<Number> modeValueFunction(String modeValue, Supplier<ModeValue<Number>> supplier) {
        ModeValue<Number> m = supplier.get();
        if (StringUtils.isNotEmpty(modeValue)) {
            String[] values = modeValue.split("_");
            if (values.length == 2) {
                try {
                    NumberFormat format = NumberFormat.getInstance();
                    m = new ModeValue<>(format.parse(values[0]), format.parse(values[1]));
                } catch (NumberFormatException | ParseException e) {
                    LOGGER.warn(e.getMessage(), e);
                }
            }
        }
        return m;
    }

    /**
     * 默认mode=scale
     */
    public static ImageDimensionMode modeFunction(String mode) {
        ImageDimensionMode m = ImageDimensionMode.SCALE;
        if (StringUtils.isNotEmpty(mode)) {
            for (ImageDimensionMode o : ImageDimensionMode.values()) {
                if (o.name().equalsIgnoreCase(mode)) {
                    m = o;
                }
            }
        }
        return m;
    }

    /**
     * 参数约束检验
     */
    public static String validFunction(String value) {
        if (StringUtils.isNotEmpty(value)) {
            return value;
        }
        throw new ArgumentInvalidException("Param source/watermark error, can't be null or empty.");
    }

    /**
     * 默认outputType=stream
     */
    public static OutputType outputTypeFunction(String outputType) {
        OutputType rs = OutputType.STREAM;
        if (StringUtils.isNotEmpty(outputType)) {
            for (OutputType p : OutputType.values()) {
                if (p.name().equalsIgnoreCase(outputType)) {
                    rs = p;
                    break;
                }
            }
        }
        return rs;
    }


    /**
     * 默认keepAspectRatio=false
     */
    public static Boolean keepAspectRatioFunction(String value) {
        return Boolean.parseBoolean(value);
    }

    /**
     * 默认positions=CENTER
     */
    public static Positions positionsFunction(String positions) {
        Positions rs = Positions.CENTER;
        if (StringUtils.isNotEmpty(positions)) {
            for (Positions p : Positions.values()) {
                if (p.name().equalsIgnoreCase(positions)) {
                    rs = p;
                    break;
                }
            }
        }
        return rs;
    }


    /**
     * 默认watermarkOpacity=0.8f
     */
    public static float watermarkOpacityFunction(String watermarkOpacity) {
        float rs = 0.8f;
        if (StringUtils.isNotEmpty(watermarkOpacity)) {
            try {
                float v = Float.parseFloat(watermarkOpacity);
                rs = v < 0.0f ? 0.0f : v > 1.0f ? 1.0f : v;
            } catch (NumberFormatException e) {
                LOGGER.warn(e.getMessage(), e);
            }
        }
        return rs;
    }


    /**
     * 默认quality=1.0d
     */
    public static double qualityFunction(String quality) {
        double rs = 1.0d;
        if (StringUtils.isNotEmpty(quality)) {
            try {
                double v = Double.parseDouble(quality);
                rs = v < 0.0d ? 0.0d : v > 1.0d ? 1.0d : v;
            } catch (NumberFormatException e) {
                LOGGER.warn(e.getMessage(), e);
            }
        }
        return rs;
    }


    /**
     * 默认rotateAngle=0.0d
     */
    public static double rotateAngleFunction(String rotateAngle) {
        double rs = 0.0d;
        if (StringUtils.isNotEmpty(rotateAngle)) {
            try {
                rs = Double.parseDouble(rotateAngle);
            } catch (NumberFormatException e) {
                LOGGER.warn(e.getMessage(), e);
            }
        }
        return rs;
    }


    public final String paramName;

    Param(String paramName) {
        this.paramName = paramName;
    }

    /**
     * Author : secondriver
     * Date :  2016/1/5
     */
    public static class ModeValue<T> {
        public final T width;
        public final T height;

        public ModeValue(T width, T height) {
            this.width = width;
            this.height = height;
        }
    }

    /**
     * Author : secondriver
     * Date :  2016/1/5
     */
    public enum ImageDimensionMode {
        SIZE, SCALE
    }

    public enum OutputType {
        STREAM, URL, BASE64;
    }
}